/*
 * @Author: Kiro AI Assistant
 * @Date: 2025-01-10
 * @Description: 悬浮播放器管理器 - 迁移自原项目并适配 MVVM 架构
 * 
 * 功能特性：
 * - 独立的悬浮播放器模块
 * - 支持拖拽和吸附边缘
 * - 集成 MusicPlayerViewModel 状态监听
 * - pill 形态和圆形形态切换
 * - 点击返回播放页面功能
 */

import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../viewmodels/music_player_view_model.dart';
import '../pages/music_player_page.dart';

/// 悬浮播放器初始位置枚举
enum FloatingPlayerPosition {
  /// 左上角
  topLeft,

  /// 右上角
  topRight,

  /// 左下角
  bottomLeft,

  /// 右下角
  bottomRight,
}

/// 悬浮播放器配置类
class FloatingPlayerConfig {
  /// 默认位置坐标
  final double x;
  final double y;

  /// 宽高尺寸
  final double width;
  final double height;

  /// 基础样式配置
  final Color backgroundColor;
  final double borderRadius;
  final Color iconColor;
  final IconData defaultIcon;
  final double padding;

  /// 初始位置枚举
  final FloatingPlayerPosition initialPosition;

  /// 是否启用拖拽
  final bool enableDrag;

  /// 是否启用旋转动画
  final bool enableRotation;

  const FloatingPlayerConfig({
    this.x = 0,
    this.y = 160,
    this.width = 98, // pill形态宽度
    this.height = 64, // 固定高度
    this.backgroundColor = const Color(0x80FFFFFF),
    this.borderRadius = 28,
    this.iconColor = Colors.white,
    this.defaultIcon = Icons.music_note_rounded,
    this.padding = 6,
    this.initialPosition = FloatingPlayerPosition.bottomRight,
    this.enableDrag = true,
    this.enableRotation = true,
  });

  /// 复制配置并修改部分参数
  FloatingPlayerConfig copyWith({
    double? x,
    double? y,
    double? width,
    double? height,
    Color? backgroundColor,
    double? borderRadius,
    Color? iconColor,
    IconData? defaultIcon,
    double? padding,
    FloatingPlayerPosition? initialPosition,
    bool? enableDrag,
    bool? enableRotation,
  }) {
    return FloatingPlayerConfig(
      x: x ?? this.x,
      y: y ?? this.y,
      width: width ?? this.width,
      height: height ?? this.height,
      backgroundColor: backgroundColor ?? this.backgroundColor,
      borderRadius: borderRadius ?? this.borderRadius,
      iconColor: iconColor ?? this.iconColor,
      defaultIcon: defaultIcon ?? this.defaultIcon,
      padding: padding ?? this.padding,
      initialPosition: initialPosition ?? this.initialPosition,
      enableDrag: enableDrag ?? this.enableDrag,
      enableRotation: enableRotation ?? this.enableRotation,
    );
  }
}

/// 悬浮播放器状态类
class FloatingPlayerState {
  /// 是否可见
  final bool visible;

  /// 是否正在拖拽
  final bool isDragging;

  /// 当前位置
  final double left;
  final double top;

  /// 保存的位置（用于hide/restore）
  final double? savedLeft;
  final double? savedTop;

  /// 当前播放信息
  final String? title;
  final String? artist;
  final String? albumArt;
  final bool isPlaying;

  /// 当前样式
  final Color backgroundColor;
  final Color iconColor;
  final double size;

  /// 配置信息
  final FloatingPlayerConfig config;

  const FloatingPlayerState({
    required this.visible,
    required this.isDragging,
    required this.left,
    required this.top,
    this.savedLeft,
    this.savedTop,
    this.title,
    this.artist,
    this.albumArt,
    required this.isPlaying,
    required this.backgroundColor,
    required this.iconColor,
    required this.size,
    required this.config,
  });

  /// 创建初始状态
  factory FloatingPlayerState.initial(FloatingPlayerConfig config) {
    return FloatingPlayerState(
      visible: false,
      isDragging: false,
      left: config.x,
      top: config.y,
      isPlaying: false,
      backgroundColor: config.backgroundColor,
      iconColor: config.iconColor,
      size: config.height,
      config: config,
    );
  }

  /// 复制状态并修改部分参数
  FloatingPlayerState copyWith({
    bool? visible,
    bool? isDragging,
    double? left,
    double? top,
    double? savedLeft,
    double? savedTop,
    String? title,
    String? artist,
    String? albumArt,
    bool? isPlaying,
    Color? backgroundColor,
    Color? iconColor,
    double? size,
    FloatingPlayerConfig? config,
  }) {
    return FloatingPlayerState(
      visible: visible ?? this.visible,
      isDragging: isDragging ?? this.isDragging,
      left: left ?? this.left,
      top: top ?? this.top,
      savedLeft: savedLeft ?? this.savedLeft,
      savedTop: savedTop ?? this.savedTop,
      title: title ?? this.title,
      artist: artist ?? this.artist,
      albumArt: albumArt ?? this.albumArt,
      isPlaying: isPlaying ?? this.isPlaying,
      backgroundColor: backgroundColor ?? this.backgroundColor,
      iconColor: iconColor ?? this.iconColor,
      size: size ?? this.size,
      config: config ?? this.config,
    );
  }

  /// 计算初始位置
  Offset calculateInitialPosition(Size screenSize, EdgeInsets padding) {
    const marginBottom = 100.0;
    const marginTop = 12.0;

    switch (config.initialPosition) {
      case FloatingPlayerPosition.topLeft:
        return Offset(
          0,
          math.max(marginTop + padding.top, 56.0 + padding.top),
        );
      case FloatingPlayerPosition.topRight:
        return Offset(
          screenSize.width - config.width,
          math.max(marginTop + padding.top, 56.0 + padding.top),
        );
      case FloatingPlayerPosition.bottomLeft:
        return Offset(
          0,
          screenSize.height - config.height - (padding.bottom + marginBottom),
        );
      case FloatingPlayerPosition.bottomRight:
        return Offset(
          screenSize.width - config.width,
          screenSize.height - config.height - (padding.bottom + marginBottom),
        );
    }
  }

  /// 获取拖拽时的尺寸（圆形）
  double get draggingSize => config.height;

  /// 获取pill形态的宽度
  double get pillWidth => config.width;
}

/// 悬浮播放器管理器
/// 实现完全解耦的静态接口，集成 MusicPlayerViewModel
class FloatingPlayerManager {
  static FloatingPlayerManager? _instance;
  static FloatingPlayerManager get instance =>
      _instance ??= FloatingPlayerManager._();

  FloatingPlayerManager._();

  /// 控制器实例
  _FloatingPlayerController? _controller;

  /// 初始化悬浮播放器模块
  /// 支持多次调用，只会初始化一次
  static void initialize(
    BuildContext context, {
    FloatingPlayerConfig? config,
  }) {
    final manager = FloatingPlayerManager.instance;
    if (manager._controller != null) {
      debugPrint('FloatingPlayerManager: 已经初始化，跳过重复初始化');
      return;
    }

    // 检查 Overlay 是否可用
    final overlay = Overlay.maybeOf(context, rootOverlay: true);
    if (overlay == null) {
      debugPrint('FloatingPlayerManager: Overlay 不可用，跳过初始化');
      return;
    }

    final finalConfig = config ?? const FloatingPlayerConfig();

    try {
      manager._controller = _FloatingPlayerController(
        overlay: overlay,
        config: finalConfig,
      );

      // 延迟到下一帧插入Overlay
      WidgetsBinding.instance.addPostFrameCallback((_) {
        manager._controller?._ensureEntryInserted();
      });

      debugPrint('FloatingPlayerManager: 初始化成功');
    } catch (e) {
      debugPrint('FloatingPlayerManager: 初始化失败 - $e');
      manager._controller = null;
    }
  }

  /// 显示悬浮播放器
  /// 根据当前播放状态自动显示
  static void show(BuildContext context) {
    final manager = FloatingPlayerManager.instance;
    final musicPlayerViewModel = context.read<MusicPlayerViewModel>();

    // 只有在有播放内容时才显示
    if (musicPlayerViewModel.hasCurrentTrack) {
      manager._controller?.show(context);
    }
  }

  /// 隐藏悬浮播放器
  /// 保留完整状态信息
  static void hide() {
    final manager = FloatingPlayerManager.instance;
    manager._controller?.hide();
  }

  /// 关闭悬浮播放器
  /// 彻底重置状态和释放资源
  static void close() {
    final manager = FloatingPlayerManager.instance;
    manager._controller?.close();
  }

  /// 恢复悬浮播放器
  /// 从隐藏状态恢复到之前的位置
  static void restore(BuildContext context) {
    final manager = FloatingPlayerManager.instance;
    manager._controller?.restore(context);
  }

  /// 获取当前状态
  static FloatingPlayerState? get currentState {
    final manager = FloatingPlayerManager.instance;
    return manager._controller?.currentState;
  }

  /// 是否正在显示
  static bool get isShowing {
    return currentState?.visible == true;
  }

  /// 更新播放状态
  static void updatePlayingState(BuildContext context) {
    final manager = FloatingPlayerManager.instance;
    manager._controller?.updatePlayingState(context);
  }

  /// 销毁管理器实例
  static void dispose() {
    final manager = FloatingPlayerManager.instance;
    manager._controller?.dispose();
    manager._controller = null;
    _instance = null;
  }
}

/// 内部控制器类
/// 负责具体的状态管理和UI控制
class _FloatingPlayerController {
  final OverlayState overlay;
  final FloatingPlayerConfig config;

  OverlayEntry? _entry;
  late final ValueNotifier<FloatingPlayerState> _stateNotifier;
  bool _pendingInsert = false;

  _FloatingPlayerController({
    required this.overlay,
    required this.config,
  }) {
    _stateNotifier = ValueNotifier(FloatingPlayerState.initial(config));
  }

  /// 获取当前状态
  FloatingPlayerState get currentState => _stateNotifier.value;

  /// 确保OverlayEntry已插入
  void _ensureEntryInserted() {
    _entry ??= OverlayEntry(
      builder: (context) =>
          _FloatingPlayerWidget(stateNotifier: _stateNotifier),
    );

    if (_entryInserted || _pendingInsert) return;

    _pendingInsert = true;
    WidgetsBinding.instance.addPostFrameCallback((_) {
      if (!_entryInserted && overlay.mounted) {
        overlay.insert(_entry!);
      }
      _pendingInsert = false;
    });
  }

  bool get _entryInserted => _entry?.mounted == true;

  /// 显示悬浮播放器
  void show(BuildContext context) {
    _ensureEntryInserted();

    final musicPlayerViewModel = context.read<MusicPlayerViewModel>();
    var currentState = _stateNotifier.value;

    // 如果是首次显示或从close状态恢复，使用初始位置
    if (!currentState.visible && currentState.savedLeft == null) {
      currentState = _updateInitialPosition(currentState);
    }

    _stateNotifier.value = currentState.copyWith(
      visible: true,
      title: musicPlayerViewModel.currentTrackTitle,
      artist: musicPlayerViewModel.currentTrackArtist,
      albumArt: musicPlayerViewModel.currentTrackAlbumArt,
      isPlaying: musicPlayerViewModel.isPlaying.value,
    );
  }

  /// 隐藏悬浮播放器（保留状态）
  void hide() {
    final currentState = _stateNotifier.value;
    if (!currentState.visible) return;

    _stateNotifier.value = currentState.copyWith(
      visible: false,
      savedLeft: currentState.left,
      savedTop: currentState.top,
    );
  }

  /// 恢复悬浮播放器
  void restore(BuildContext context) {
    final currentState = _stateNotifier.value;
    if (currentState.visible) return;

    final musicPlayerViewModel = context.read<MusicPlayerViewModel>();

    // 只有在有播放内容时才恢复显示
    if (musicPlayerViewModel.hasCurrentTrack) {
      _stateNotifier.value = currentState.copyWith(
        visible: true,
        left: currentState.savedLeft ?? currentState.left,
        top: currentState.savedTop ?? currentState.top,
        title: musicPlayerViewModel.currentTrackTitle,
        artist: musicPlayerViewModel.currentTrackArtist,
        albumArt: musicPlayerViewModel.currentTrackAlbumArt,
        isPlaying: musicPlayerViewModel.isPlaying.value,
      );
    }
  }

  /// 关闭悬浮播放器（重置状态）
  void close() {
    _stateNotifier.value = _stateNotifier.value.copyWith(
      visible: false,
      savedLeft: null,
      savedTop: null,
    );
  }

  /// 更新初始位置
  FloatingPlayerState _updateInitialPosition(FloatingPlayerState state) {
    final context = overlay.context;
    if (!context.mounted) return state;

    final screenSize = MediaQuery.of(context).size;
    final padding = MediaQuery.of(context).padding;

    final initialOffset = state.calculateInitialPosition(
      screenSize,
      padding,
    );

    return state.copyWith(
      left: initialOffset.dx,
      top: initialOffset.dy,
    );
  }

  /// 更新位置
  void updatePosition(double left, double top) {
    _stateNotifier.value = _stateNotifier.value.copyWith(
      left: left,
      top: top,
    );
  }

  /// 更新拖拽状态
  void updateDragging(bool isDragging) {
    _stateNotifier.value = _stateNotifier.value.copyWith(
      isDragging: isDragging,
    );
  }

  /// 更新播放状态
  void updatePlayingState(BuildContext context) {
    final musicPlayerViewModel = context.read<MusicPlayerViewModel>();
    _stateNotifier.value = _stateNotifier.value.copyWith(
      title: musicPlayerViewModel.currentTrackTitle,
      artist: musicPlayerViewModel.currentTrackArtist,
      albumArt: musicPlayerViewModel.currentTrackAlbumArt,
      isPlaying: musicPlayerViewModel.isPlaying.value,
    );
  }

  /// 销毁控制器
  void dispose() {
    _entry?.remove();
    _entry = null;
    _stateNotifier.dispose();
  }
}

/// 悬浮播放器UI组件
/// 负责渲染和交互处理
class _FloatingPlayerWidget extends StatefulWidget {
  final ValueNotifier<FloatingPlayerState> stateNotifier;

  const _FloatingPlayerWidget({
    required this.stateNotifier,
  });

  @override
  State<_FloatingPlayerWidget> createState() => _FloatingPlayerWidgetState();
}

class _FloatingPlayerWidgetState extends State<_FloatingPlayerWidget>
    with TickerProviderStateMixin {
  late FloatingPlayerState _state;
  late AnimationController _snapController;
  late AnimationController _rotationController;

  @override
  void initState() {
    super.initState();
    _state = widget.stateNotifier.value;

    _snapController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 220),
    );

    _rotationController = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 10),
    );

    if (_state.config.enableRotation) {
      _rotationController.repeat();
    }

    widget.stateNotifier.addListener(_onStateChanged);
  }

  @override
  void dispose() {
    widget.stateNotifier.removeListener(_onStateChanged);
    _snapController.dispose();
    _rotationController.dispose();
    super.dispose();
  }

  /// 状态变化处理
  void _onStateChanged() {
    if (mounted) {
      final oldEnableRotation = _state.config.enableRotation;

      WidgetsBinding.instance.addPostFrameCallback((_) {
        if (mounted) {
          setState(() {
            _state = widget.stateNotifier.value;
          });

          // 处理旋转动画状态变化
          if (oldEnableRotation != _state.config.enableRotation) {
            if (_state.config.enableRotation) {
              _rotationController.repeat();
            } else {
              _rotationController.stop();
            }
          }
        }
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    if (!_state.visible) return const SizedBox.shrink();

    return Positioned(
      left: _state.left,
      top: _state.top,
      child: _buildFloatingPlayer(),
    );
  }

  /// 构建悬浮播放器
  Widget _buildFloatingPlayer() {
    final screenSize = MediaQuery.of(context).size;

    // 当前形态下的宽高
    final currentWidth =
        _state.isDragging ? _state.draggingSize : _state.pillWidth;
    final currentHeight = _state.draggingSize;

    // 保护位置
    final safeLeft = _clampLeft(screenSize, _state.left, currentWidth);

    // 判断靠左还是靠右
    final isLeftSide = (safeLeft + currentWidth / 2) < screenSize.width / 2;

    return Material(
      color: Colors.transparent,
      child: GestureDetector(
        onPanStart: _state.config.enableDrag
            ? (details) => _onPanStart(details, screenSize)
            : null,
        onPanUpdate: _state.config.enableDrag
            ? (details) => _onPanUpdate(details, screenSize)
            : null,
        onPanEnd: _state.config.enableDrag
            ? (details) => _onPanEnd(details, screenSize)
            : null,
        child: AnimatedContainer(
          duration: const Duration(milliseconds: 180),
          curve: Curves.easeOut,
          decoration: BoxDecoration(
            color: _state.backgroundColor,
            borderRadius: _state.isDragging
                ? BorderRadius.circular(currentHeight)
                : BorderRadius.horizontal(
                    left: Radius.circular(isLeftSide ? 0 : currentHeight / 2),
                    right: Radius.circular(isLeftSide ? currentHeight / 2 : 0),
                  ),
            boxShadow: [
              BoxShadow(
                color: Colors.black.withOpacity(0.25),
                blurRadius: 10,
                offset: const Offset(0, 6),
              ),
            ],
          ),
          padding: EdgeInsets.all(_state.config.padding),
          child: _state.isDragging
              ? _buildCenterContent()
              : _buildPillContent(isLeftSide: isLeftSide),
        ),
      ),
    );
  }

  /// 构建圆形形态的居中内容
  Widget _buildCenterContent() {
    final size = _state.draggingSize - _state.config.padding * 2;
    return Center(
      child: _buildAlbumCoverOrIcon(size),
    );
  }

  /// 构建pill形态的内容
  Widget _buildPillContent({required bool isLeftSide}) {
    final avatarSize = _state.draggingSize - _state.config.padding * 2;

    var avatar = _state.config.enableRotation
        ? RotationTransition(
            turns: Tween(begin: 0.0, end: 1.0).animate(
              CurvedAnimation(
                parent: _rotationController,
                curve: Curves.linear,
              ),
            ),
            child: _buildAlbumCoverOrIcon(avatarSize),
          )
        : _buildAlbumCoverOrIcon(avatarSize);

    // 点击专辑封面返回播放页面
    avatar = InkWell(
      onTap: () => _navigateToPlayerPage(),
      child: avatar,
    );

    final closeButton = InkWell(
      borderRadius: BorderRadius.circular(12),
      onTap: () {
        // 关闭悬浮播放器
        FloatingPlayerManager.close();
      },
      child: Container(
        width: 32,
        height: 32,
        alignment: Alignment.center,
        child: Icon(
          Icons.close,
          size: 28,
          color: _state.iconColor,
        ),
      ),
    );

    const gap = SizedBox(width: 2);

    return Row(
      mainAxisSize: MainAxisSize.min,
      mainAxisAlignment:
          isLeftSide ? MainAxisAlignment.end : MainAxisAlignment.start,
      children: isLeftSide
          ? <Widget>[closeButton, gap, avatar]
          : <Widget>[avatar, gap, closeButton],
    );
  }

  /// 构建专辑封面或图标
  Widget _buildAlbumCoverOrIcon(double size) {
    Widget content;

    if (_state.albumArt != null && _state.albumArt!.isNotEmpty) {
      content = Image.network(
        _state.albumArt!,
        fit: BoxFit.cover,
        errorBuilder: (context, error, stackTrace) {
          return Icon(
            _state.isPlaying ? Icons.pause : Icons.play_arrow,
            size: size * 0.7,
            color: _state.iconColor,
          );
        },
        loadingBuilder: (context, child, loadingProgress) {
          if (loadingProgress == null) return child;
          return Center(
            child: CircularProgressIndicator(
              value: loadingProgress.expectedTotalBytes != null
                  ? loadingProgress.cumulativeBytesLoaded /
                      loadingProgress.expectedTotalBytes!
                  : null,
              strokeWidth: 2.0,
              valueColor: AlwaysStoppedAnimation<Color>(_state.iconColor),
            ),
          );
        },
      );
    } else {
      content = Icon(
        _state.isPlaying ? Icons.pause : Icons.play_arrow,
        size: size * 0.6,
        color: _state.iconColor,
      );
    }

    return Container(
      width: size,
      height: size,
      padding: const EdgeInsets.all(6),
      alignment: Alignment.center,
      decoration: const BoxDecoration(
        color: Colors.black,
        shape: BoxShape.circle,
      ),
      child: ClipOval(child: content),
    );
  }

  /// 导航到播放页面
  void _navigateToPlayerPage() {
    Navigator.of(context).push(
      MaterialPageRoute(
        builder: (context) => const MusicPlayerPage(),
      ),
    );
  }

  /// 拖拽开始处理
  void _onPanStart(DragStartDetails details, Size screenSize) {
    final controller = FloatingPlayerManager.instance._controller;
    controller?.updateDragging(true);
  }

  /// 拖拽更新处理
  void _onPanUpdate(DragUpdateDetails details, Size screenSize) {
    final controller = FloatingPlayerManager.instance._controller;
    final w = _state.draggingSize;
    final h = _state.draggingSize;
    final newLeft = _clampLeft(screenSize, _state.left + details.delta.dx, w);
    final newTop = _clampTop(screenSize, _state.top + details.delta.dy, h);
    controller?.updatePosition(newLeft, newTop);
  }

  /// 拖拽结束处理
  void _onPanEnd(DragEndDetails details, Size screenSize) {
    final controller = FloatingPlayerManager.instance._controller;
    final targetWidth = _state.pillWidth;
    final targetLeft = _targetLeftForSnap(screenSize, targetWidth);

    final begin = _state.left;
    final diff = targetLeft - begin;

    _snapController.reset();
    _snapController.addListener(() {
      final t = Curves.easeOut.transform(_snapController.value);
      controller?.updatePosition(begin + diff * t, _state.top);
    });

    _snapController.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        controller?.updateDragging(false);
      }
    });

    _snapController.forward();
  }

  /// 计算吸附目标X坐标
  double _targetLeftForSnap(Size screen, double width) {
    final centerX = _state.left + width / 2;
    final onLeft = centerX < screen.width / 2;
    return onLeft ? 0 : (screen.width - width);
  }

  /// 限制垂直位置
  double _clampTop(Size screen, double top, double height) {
    final padding = MediaQuery.of(context).padding;
    final minTop = math.max(12 + padding.top, 56.0 + padding.top);
    final maxTop = screen.height - height - (padding.bottom + 24);
    return top.clamp(minTop, maxTop);
  }

  /// 限制水平位置
  double _clampLeft(Size screen, double left, double width) {
    return left.clamp(0, screen.width - width);
  }
}

/// 悬浮播放器初始化器组件
/// 用于在应用根部初始化悬浮播放器
class FloatingPlayerInitializer extends StatefulWidget {
  final Widget child;
  final FloatingPlayerConfig? config;

  const FloatingPlayerInitializer({
    super.key,
    required this.child,
    this.config,
  });

  @override
  State<FloatingPlayerInitializer> createState() =>
      _FloatingPlayerInitializerState();
}

class _FloatingPlayerInitializerState extends State<FloatingPlayerInitializer> {
  bool _initialized = false;

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    if (!_initialized) {
      // 延迟初始化，确保 Overlay 已经可用
      WidgetsBinding.instance.addPostFrameCallback((_) {
        if (mounted) {
          try {
            FloatingPlayerManager.initialize(context, config: widget.config);
            _initialized = true;
          } catch (e) {
            debugPrint('FloatingPlayerManager 初始化失败: $e');
          }
        }
      });
    }
  }

  @override
  Widget build(BuildContext context) => widget.child;
}
